package iputil_test

import (
	"testing"

	"github.com/ipinfo/cli/lib/iputil"
	"github.com/stretchr/testify/assert"
)

func assertCIDRsFromIPRangeStrRaw(
	t *testing.T,
	start string,
	end string,
	cidrs []string,
) {
	var _cidrs []string
	var err error

	_cidrs, err = iputil.CIDRsFromIPRangeStrRaw(start + "-" + end)
	assert.Nil(t, err)
	assert.Equal(t, len(cidrs), len(_cidrs))
	for i := 0; i < len(cidrs); i++ {
		assert.Equal(t, cidrs[i], _cidrs[i])
	}

	// test reverse direction
	_cidrs, err = iputil.CIDRsFromIPRangeStrRaw(end + "-" + start)
	assert.Nil(t, err)
	assert.Equal(t, len(cidrs), len(_cidrs))
	for i := len(cidrs) - 1; i >= 0; i-- {
		assert.Equal(t, cidrs[i], _cidrs[(len(cidrs)-1)-i])
	}
}

func TestCIDRsFromIPRangeStrRaw(t *testing.T) {
	assertCIDRsFromIPRangeStrRaw(
		t, "1.1.1.0", "1.1.1.0",
		[]string{
			"1.1.1.0/32",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "1.1.1.0", "1.1.1.1",
		[]string{
			"1.1.1.0/31",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "1.1.1.0", "1.1.1.2",
		[]string{
			"1.1.1.0/31",
			"1.1.1.2/32",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "1.1.1.0", "1.1.1.3",
		[]string{
			"1.1.1.0/30",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "1.1.1.5", "1.1.1.55",
		[]string{
			"1.1.1.5/32",
			"1.1.1.6/31",
			"1.1.1.8/29",
			"1.1.1.16/28",
			"1.1.1.32/28",
			"1.1.1.48/29",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "24.24.24.24", "50.50.50.50",
		[]string{
			"24.24.24.24/29",
			"24.24.24.32/27",
			"24.24.24.64/26",
			"24.24.24.128/25",
			"24.24.25.0/24",
			"24.24.26.0/23",
			"24.24.28.0/22",
			"24.24.32.0/19",
			"24.24.64.0/18",
			"24.24.128.0/17",
			"24.25.0.0/16",
			"24.26.0.0/15",
			"24.28.0.0/14",
			"24.32.0.0/11",
			"24.64.0.0/10",
			"24.128.0.0/9",
			"25.0.0.0/8",
			"26.0.0.0/7",
			"28.0.0.0/6",
			"32.0.0.0/4",
			"48.0.0.0/7",
			"50.0.0.0/11",
			"50.32.0.0/12",
			"50.48.0.0/15",
			"50.50.0.0/19",
			"50.50.32.0/20",
			"50.50.48.0/23",
			"50.50.50.0/27",
			"50.50.50.32/28",
			"50.50.50.48/31",
			"50.50.50.50/32",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "0.0.0.0", "255.255.255.254",
		[]string{
			"0.0.0.0/1",
			"128.0.0.0/2",
			"192.0.0.0/3",
			"224.0.0.0/4",
			"240.0.0.0/5",
			"248.0.0.0/6",
			"252.0.0.0/7",
			"254.0.0.0/8",
			"255.0.0.0/9",
			"255.128.0.0/10",
			"255.192.0.0/11",
			"255.224.0.0/12",
			"255.240.0.0/13",
			"255.248.0.0/14",
			"255.252.0.0/15",
			"255.254.0.0/16",
			"255.255.0.0/17",
			"255.255.128.0/18",
			"255.255.192.0/19",
			"255.255.224.0/20",
			"255.255.240.0/21",
			"255.255.248.0/22",
			"255.255.252.0/23",
			"255.255.254.0/24",
			"255.255.255.0/25",
			"255.255.255.128/26",
			"255.255.255.192/27",
			"255.255.255.224/28",
			"255.255.255.240/29",
			"255.255.255.248/30",
			"255.255.255.252/31",
			"255.255.255.254/32",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "0.0.0.0", "255.255.255.255",
		[]string{
			"0.0.0.0/0",
		},
	)
	assertCIDRsFromIPRangeStrRaw(
		t, "0.0.0.1", "255.255.255.254",
		[]string{
			"0.0.0.1/32",
			"0.0.0.2/31",
			"0.0.0.4/30",
			"0.0.0.8/29",
			"0.0.0.16/28",
			"0.0.0.32/27",
			"0.0.0.64/26",
			"0.0.0.128/25",
			"0.0.1.0/24",
			"0.0.2.0/23",
			"0.0.4.0/22",
			"0.0.8.0/21",
			"0.0.16.0/20",
			"0.0.32.0/19",
			"0.0.64.0/18",
			"0.0.128.0/17",
			"0.1.0.0/16",
			"0.2.0.0/15",
			"0.4.0.0/14",
			"0.8.0.0/13",
			"0.16.0.0/12",
			"0.32.0.0/11",
			"0.64.0.0/10",
			"0.128.0.0/9",
			"1.0.0.0/8",
			"2.0.0.0/7",
			"4.0.0.0/6",
			"8.0.0.0/5",
			"16.0.0.0/4",
			"32.0.0.0/3",
			"64.0.0.0/2",
			"128.0.0.0/2",
			"192.0.0.0/3",
			"224.0.0.0/4",
			"240.0.0.0/5",
			"248.0.0.0/6",
			"252.0.0.0/7",
			"254.0.0.0/8",
			"255.0.0.0/9",
			"255.128.0.0/10",
			"255.192.0.0/11",
			"255.224.0.0/12",
			"255.240.0.0/13",
			"255.248.0.0/14",
			"255.252.0.0/15",
			"255.254.0.0/16",
			"255.255.0.0/17",
			"255.255.128.0/18",
			"255.255.192.0/19",
			"255.255.224.0/20",
			"255.255.240.0/21",
			"255.255.248.0/22",
			"255.255.252.0/23",
			"255.255.254.0/24",
			"255.255.255.0/25",
			"255.255.255.128/26",
			"255.255.255.192/27",
			"255.255.255.224/28",
			"255.255.255.240/29",
			"255.255.255.248/30",
			"255.255.255.252/31",
			"255.255.255.254/32",
		},
	)
}
